package vip.fuxk.neav.service;

import org.noear.redisx.RedisClient;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.cloud.gateway.CloudRouteRegister;
import org.noear.solon.core.route.PathRule;
import org.noear.solon.data.cache.CacheService;
import vip.fuxk.neav.Cons;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


@Component
public class SubAppService {

    @Inject
    public RedisClient redisClient;

    @Inject
    public CacheService cacheService;

    @Inject
    public CloudRouteRegister register;


    public Map<String,PathRule> groupPathRules = new ConcurrentHashMap<>();

    public void toggleServer(String group,String server){
        String activeKey = Cons.SUB_APP.GROUP_SERVER_ACTIVE(group);
        redisClient.jedis().set(activeKey,server);
        addGroupPathRule(group,Cons.SUB_APP.GROUP_DEFAULT_PATH(group));
    }

    public void addGroupPathRule(String group,String path){
        if(path == null || path.isEmpty()){
            return;
        }
        String groupPathRuleKey = Cons.SUB_APP.GROUP_PATH_RULE(group);
        String groupPathRule = redisClient.jedis().get(groupPathRuleKey);
        if(groupPathRule == null || groupPathRule.isEmpty()){
            groupPathRule = path;
        }else{
            List<String> pathList = Arrays.stream(groupPathRule.split(",")).collect(Collectors.toList());
            if(!pathList.contains(path)){
                groupPathRule = groupPathRule+","+path;
            }
        }
        String[] split = groupPathRule.split(",");
        PathRule pathRule = new PathRule();
        for (String p : split) {
            pathRule.include(p);
        }
        groupPathRules.put(group,pathRule);
        redisClient.jedis().set(groupPathRuleKey,groupPathRule);
    }


    public Boolean register(String group,String server){
        String heartbeatKey = Cons.SUB_APP.HEARTBEAT_KEY(group,server);
        String activeKey = Cons.SUB_APP.GROUP_SERVER_ACTIVE(group);
        String currActive = cacheService.get(activeKey,String.class);
        // 当前服务实例
        if(currActive == null || currActive.isEmpty()){
            this.toggleServer(group,server);
        }
        if(!groupPathRules.containsKey(group)){
            addGroupPathRule(group,Cons.SUB_APP.GROUP_DEFAULT_PATH(group));
        }

        register.route(group, r -> r.path(Cons.SUB_APP.GROUP_DEFAULT_PATH(group))
                .target(server));
        // 心跳
        redisClient.jedis().setex(heartbeatKey, 3,server);
        return true;
    }

    public Map.Entry<String,PathRule> tryMatchSub(String path) {
        for(Map.Entry<String,PathRule> entry : groupPathRules.entrySet()){
            if (entry.getValue().test(path)) {
                return entry;
            }
        }
        return null;
    }

    public String getServerByGroup(String group) {
        String activeKey = Cons.SUB_APP.GROUP_SERVER_ACTIVE(group);
        return redisClient.jedis().get(activeKey);
    }
}
